using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Configuration;
using System.Configuration;
using System.Configuration.Provider;

namespace Systepic.Projects
{
	/// <summary>
	/// Class statically instantiating the providers
	/// specified in the app.config or web.config. This
	/// class houses the providers and should be used
	/// to access the providers.
	/// </summary>
	public class ProjectsService
	{
		//Initialization related variables and logic
		private static bool isInitialized = false;
		private static Exception initializationException;
		private static object initializationLock = new object();
		// Public feature API
		private static ProjectsProvider defaultProvider;
		private static ProjectsProviderCollection providerCollection;

		/// <summary>
		/// Calls initialization.
		/// </summary>
		static ProjectsService()
		{
			Initialize();
		}

		/// <summary>
		/// Called when the ProjectService's
		/// static constructor is called. Instantiates
		/// ProjectProviders specifed in the app.config
		/// file. 
		/// </summary>
		public static void Initialize()
		{
			try
			{
				//Get the feature's configuration info
				ProjectsConfiguration bc =
					(ProjectsConfiguration)
					ConfigurationManager.GetSection("Projects");

				// There are no providers specified
				// or no default provider.
				if (bc.DefaultProvider == null ||
					bc.Providers == null ||
					bc.Providers.Count < 1)
					throw new ProviderException(
						"You must specify a valid default provider.");

				// Instantiate the providers
				providerCollection = new ProjectsProviderCollection();
				ProvidersHelper.InstantiateProviders(bc.Providers,
					providerCollection, typeof(ProjectsProvider));
				providerCollection.SetReadOnly();
				defaultProvider = providerCollection[bc.DefaultProvider];

				// The default provider doesn't exist
				if (defaultProvider == null)
				{
					throw new ConfigurationErrorsException(
						"You must specify a default provider for the feature.",
						bc.ElementInformation.Properties["defaultProvider"].Source,
						bc.ElementInformation.Properties["defaultProvider"].LineNumber);
				}
			}
			catch (Exception ex)
			{
				initializationException = ex;
				throw ex;
			}

			isInitialized = true; //error-free initialization
		}

		/// <summary>
		/// Get primary provider specified in the app.config
		/// </summary>
		public static ProjectsProvider Provider
		{
			get { return defaultProvider; }
		}

		/// <summary>
		/// Get all of the providers specified in 
		/// the app.config.
		/// </summary>
		public static ProjectsProviderCollection Providers
		{
			get { return providerCollection; }
		}

		/// <summary>
		/// Get whether or not the providers were
		/// initialized properly.
		/// </summary>
		public static bool IsInitialized
		{
			get { return isInitialized; }
		}
	}
}
